package com.rickpan.repository;

import com.rickpan.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 用户数据访问层
 */
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 根据用户名查找用户
     */
    Optional<User> findByUsername(String username);

    /**
     * 根据邮箱查找用户
     */
    Optional<User> findByEmail(String email);

    /**
     * 根据用户名或邮箱查找用户
     */
    @Query("SELECT u FROM User u WHERE u.username = :usernameOrEmail OR u.email = :usernameOrEmail")
    Optional<User> findByUsernameOrEmail(@Param("usernameOrEmail") String usernameOrEmail);

    /**
     * 检查用户名是否存在
     */
    boolean existsByUsername(String username);

    /**
     * 检查邮箱是否存在
     */
    boolean existsByEmail(String email);

    /**
     * 根据状态查找用户
     */
    @Query("SELECT u FROM User u WHERE u.status = :status")
    Optional<User> findByStatus(@Param("status") User.Status status);

    /**
     * 统计活跃用户数量
     */
    @Query("SELECT COUNT(u) FROM User u WHERE u.status = 'ACTIVE'")
    long countActiveUsers();

    /**
     * 统计总存储使用量
     */
    @Query("SELECT SUM(u.storageUsed) FROM User u WHERE u.status = 'ACTIVE'")
    Long getTotalStorageUsed();

    /**
     * 原子性更新用户存储使用量
     * 使用数据库级别的原子操作，避免并发冲突
     */
    @Modifying
    @Query("UPDATE User u SET u.storageUsed = u.storageUsed + :fileSize, u.updatedAt = CURRENT_TIMESTAMP WHERE u.id = :userId")
    int updateStorageUsed(@Param("userId") Long userId, @Param("fileSize") Long fileSize);

    // 悲观锁方法已移除，使用简单重试机制

    /**
     * 根据用户名模糊搜索用户
     */
    List<User> findByUsernameContainingIgnoreCase(String username);

    /**
     * 根据邮箱模糊搜索用户
     */
    List<User> findByEmailContainingIgnoreCase(String email);

    /**
     * 根据真实姓名模糊搜索用户
     */
    List<User> findByRealNameContainingIgnoreCase(String realName);

    /**
     * 根据用户ID列表查找用户
     */
    List<User> findByIdIn(List<Long> ids);

    // =========================== VIP相关查询方法 ===========================

    /**
     * 查找已过期的VIP用户
     */
    @Query("SELECT u FROM User u WHERE u.userType = 'VIP' AND u.vipExpireTime < :now")
    List<User> findExpiredVipUsers(@Param("now") LocalDateTime now);

    /**
     * 查找即将过期的VIP用户 (指定时间范围内)
     */
    @Query("SELECT u FROM User u WHERE u.userType = 'VIP' AND u.vipExpireTime BETWEEN :now AND :futureTime")
    List<User> findExpiringVipUsers(@Param("now") LocalDateTime now, @Param("futureTime") LocalDateTime futureTime);

    /**
     * 统计VIP用户总数
     */
    @Query("SELECT COUNT(u) FROM User u WHERE u.userType = 'VIP'")
    Long countVipUsers();

    /**
     * 统计活跃VIP用户总数 (未过期)
     */
    @Query("SELECT COUNT(u) FROM User u WHERE u.userType = 'VIP' AND (u.vipExpireTime IS NULL OR u.vipExpireTime > :now)")
    Long countActiveVipUsers(@Param("now") LocalDateTime now);

    /**
     * 统计BASIC用户总数
     */
    @Query("SELECT COUNT(u) FROM User u WHERE u.userType = 'BASIC'")
    Long countBasicUsers();

    /**
     * 根据用户类型查找用户列表
     */
    List<User> findByUserTypeOrderByCreatedAtDesc(User.UserType userType);

    /**
     * 查找所有VIP用户（包括过期的）
     */
    @Query("SELECT u FROM User u WHERE u.userType = 'VIP' ORDER BY u.vipExpireTime DESC")
    List<User> findAllVipUsers();

    /**
     * 查找存储使用率高的用户 (大于指定百分比)
     */
    @Query("SELECT u FROM User u WHERE (u.storageUsed * 100.0 / u.storageQuota) > :percentage AND u.status = 'ACTIVE'")
    List<User> findUsersWithHighStorageUsage(@Param("percentage") double percentage);
}
